#! /bin/bash

## 自动修改包含版本信息源码中的版本,并提交git仓库,生成版本标签,以及下一个快照版本号
## 版本号格式为 MAJOR.MINOR.PATCH,参见脚本中 RLV_FMT_REG 正则表达式定义
## 运行前要确保所有的修改都已经提交

# 获取代码中的变量定义
function get_var(){
	echo $(sed -nr "s/^\s*##!\s*$1\s*(\S*).*$/\1/p" $2)	
}

# 根据代码中的变量定义的正则表达式获取代码中的变量定义的值
function get_value_by_reg(){
	echo $(sed -nr "s/^.*$1.*/\2/p" $2)	
}

# 检查版本号格式是否正确
function check_version_format(){
	if [[ -n "$1" && -z $(echo $1 | grep -E "$RLV_FMT_REG") ]] ;
	then
		echo "ERROR:invalid version string format(版本号格式错误),example: 1.0.0 OR 1.0.0.beta"
		exit -1
	fi
}

sh_folder=$(dirname $(readlink -f $0))

# 包含版本信息的源码文件
version_src=$sh_folder/CMakeLists.txt
version_header=$sh_folder/include/dtalk/dtalk_engine.h
conanfile_py=$sh_folder/conanfile.py

# git分支名
branch=`git branch | grep "*"`
branch=${branch/* /}
# 当前提交id
commit_id=`git rev-parse --short HEAD`

echo branch=$branch
echo commit_id=$commit_id

# 版本号格式定义
# release版本号格式
RLV_FMT_REG="([0-9]+)\.([0-9]+)\.([0-9]+)"
# 开发快照版本号格式
SS_VFMT_REG=$RLV_FMT_REG

TAG_PREFIX=$(get_var @TAG_PREFIX@  $version_src)
echo TAG_PREFIX=$TAG_PREFIX
PRJNAME_REG=$(get_var @PRJNAME_REG@  $version_src)
echo PRJNAME_REG=$PRJNAME_REG
VERSION_REG=$(get_var @VERSION_REG@  $version_src)
echo VERSION_REG=$VERSION_REG
VERSION_MAJOR_REG=$(get_var @VERSION_MAJOR_REG@  $version_src)
echo VERSION_MAJOR_REG=$VERSION_MAJOR_REG
VERSION_MINOR_REG=$(get_var @VERSION_MINOR_REG@  $version_src)
echo VERSION_MINOR_REG=$VERSION_MINOR_REG
VERSION_PATCH_REG=$(get_var @VERSION_PATCH_REG@  $version_src)
echo VERSION_PATCH_REG=$VERSION_PATCH_REG
SNAPSHOT_REG=$(get_var @SNAPSHOT_REG@  $version_src)
echo SNAPSHOT_REG=$SNAPSHOT_REG
BEANCH_REG=$(get_var @BEANCH_REG@  $version_src)
echo BEANCH_REG=$BEANCH_REG
COMMIT_REG=$(get_var @COMMIT_REG@  $version_src)
echo COMMIT_REG=$COMMIT_REG

H_VERSION_MAJOR_REG=$(get_var @H_VERSION_MAJOR_REG@  $version_src)
echo H_VERSION_MAJOR_REG=$H_VERSION_MAJOR_REG
H_VERSION_MINOR_REG=$(get_var @H_VERSION_MINOR_REG@  $version_src)
echo H_VERSION_MINOR_REG=$H_VERSION_MINOR_REG
H_VERSION_PATCH_REG=$(get_var @H_VERSION_PATCH_REG@  $version_src)
echo H_VERSION_PATCH_REG=$H_VERSION_PATCH_REG
H_VERSION_SNAPSHOT_REG=$(get_var @H_VERSION_SNAPSHOT_REG@  $version_src)
echo H_VERSION_SNAPSHOT_REG=$H_VERSION_SNAPSHOT_REG

# 从源码中获取项目名称作为为tag前缀
[ -z "$TAG_PREFIX" ] && TAG_PREFIX=$(get_value_by_reg "$PRJNAME_REG" "$version_src")-
echo TAG_PREFIX=$TAG_PREFIX
# 从源码中获取快照标志
SNAPSHOT_TAG=$(get_value_by_reg "$SNAPSHOT_REG" "$version_src")
echo SNAPSHOT_TAG=$SNAPSHOT_TAG

if [ -n "$VERSION_REG" ]
then
	# 从源码中获取当前版本号字符串
	VERSION=$(get_value_by_reg "$VERSION_REG" "$version_src")
	echo VERSION=$VERSION
	if [ -z "$VERSION" ] ;
	then
		echo "ERROR:failt to read version format from $version_src(从源码中读取版本信息失败)"
		exit -1
	fi
	# 解析版本号字符串各字段
	# 主版本号
	MAJOR_VERSION=$(echo $VERSION | sed -nr "s/$SS_VFMT_REG$SNAPSHOT_TAG/\1/p")
	# 次版本号
	MINOR_VERSION=$(echo $VERSION | sed -nr "s/$SS_VFMT_REG$SNAPSHOT_TAG/\2/p")
	# 补丁版本号
	PATCH_VERSION=$(echo $VERSION | sed -nr "s/$SS_VFMT_REG$SNAPSHOT_TAG/\3/p")

elif [ -n "$VERSION_MAJOR_REG" ] && [ -n "$VERSION_MINOR_REG" ] && [ -n "$VERSION_PATCH_REG" ]
then
	MAJOR_VERSION = $(get_value_by_reg "$VERSION_MAJOR_REG" "$version_src")
	MINOR_VERSION = $(get_value_by_reg "$VERSION_MINOR_REG" "$version_src")
	PATCH_VERSION = $(get_value_by_reg "$VERSION_PATCH_REG" "$version_src")
else
	echo "ERROR:failt to read version format from $version_src(从源码中读取版本信息失败)"
	exit -1
fi

echo MAJOR_VERSION=$MAJOR_VERSION
echo MINOR_VERSION=$MINOR_VERSION
echo PATCH_VERSION=$PATCH_VERSION

# 发行版本号(用默认值初始化)
release_version=$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION
#####################

# 提示用户输入发行版本号,如果输入为空则使用默认值
read -p "input release version(输入发行版本号)[$release_version]:" input_str

check_version_format $input_str

if [[ -n "$input_str" && -z $(echo $input_str | grep -E "$RLV_FMT_REG") ]] ;
then
	echo "ERROR:invalid version string format(版本号格式错误),example: 1.0.0 OR 1.0.0.beta"
	exit -1
fi

[ -n "$input_str" ] && release_version=$input_str

echo release_version=$release_version
input_major=$(echo $release_version | sed -nr "s/$SS_VFMT_REG(.*)/\1/p")
input_minor=$(echo $release_version | sed -nr "s/$SS_VFMT_REG(.*)/\2/p")
input_patch=$(echo $release_version | sed -nr "s/$SS_VFMT_REG(.*)/\3/p")

# 补丁版本号自动加1
new_patch=$(expr $input_patch + 1 )
echo new_patch=$new_patch
# 下一个发行版本号
next_relver=$input_major.$input_minor.$new_patch$SNAPSHOT_TAG
next_snapshot=$input_major.$input_minor.$new_patch-dev

# 提示用户输入下一个发行版本号,如果输入为空则使用默认值
read -p "input next release version(输入下一个发行版本号)[$next_relver]:" input_str

check_version_format $input_str

if [[ -n "$input_str" && -z $(echo $input_str | grep -E "$RLV_FMT_REG") ]] ;
then
	echo "ERROR:invalid version string format(版本号格式错误),example: 1.0.0 OR 1.0.0.beta"
	exit -1
fi

if [ "$input_str" = $release_version ] ;
then
	echo "ERROR:next version must not be same with $release_version(下一个版本号不能与上一个版本号相同)"
	exit -1
fi

[ -n "$input_str" ] && next_relver=$input_str
echo next_relver=$next_relver
echo next_snapshot=$next_snapshot

# 发行版本各字段
# 主版本号
rel_major_version=$(echo $release_version | sed -nr "s/$RLV_FMT_REG/\1/p")
# 次版本号
rel_minor_version=$(echo $release_version | sed -nr "s/$RLV_FMT_REG/\2/p")
# 补丁版本号
rel_patch_version=$(echo $release_version | sed -nr "s/$RLV_FMT_REG/\3/p")

# 下一个快照版本各字段
# 主版本号
snap_major_version=$(echo $next_relver | sed -nr "s/$RLV_FMT_REG.*/\1/p")
# 次版本号
snap_minor_version=$(echo $next_relver | sed -nr "s/$RLV_FMT_REG.*/\2/p")
# 补丁版本号
snap_patch_version=$(echo $next_relver | sed -nr "s/$RLV_FMT_REG.*/\3/p")

#########################
# 检查工作区是否全部有未提交的内容，有则报错退出
if [ -n "$(git status -s)" ] ;
then
	echo "ERROR:working directory not clean,can not release(工作区有未提交修改，不能执行release)"
	exit -1
fi

echo "修改源码版本号($release_version) in $version_src"
[ -z "$VERSION_REG"       ] || sed -i -r "s!$VERSION_REG!\1$release_version\3!g"         $version_src || exit
[ -z "$VERSION_MAJOR_REG" ] || sed -i -r "s!$VERSION_MAJOR_REG!\1$rel_major_version\3!g" $version_src || exit
[ -z "$VERSION_MINOR_REG" ] || sed -i -r "s!$VERSION_MINOR_REG!\1$rel_minor_version\3!g" $version_src || exit
[ -z "$VERSION_PATCH_REG" ] || sed -i -r "s!$VERSION_PATCH_REG!\1$rel_patch_version\3!g" $version_src || exit 
[ -z "$BEANCH_REG"        ] || sed -i -r "s!$BEANCH_REG!\1$branch\3!g"                   $version_src || exit
[ -z "$COMMIT_REG"        ] || sed -i -r "s!$COMMIT_REG!\1$commit_id\3!g"                $version_src || exit

if [ -f $version_header ] && [ -n "$H_VERSION_MAJOR_REG" ] && [ -n "$H_VERSION_MINOR_REG" ] && [ -n "$H_VERSION_PATCH_REG" ]
then
	echo "更新 $version_header"
	[ -z "$H_VERSION_MAJOR_REG" ] || sed -i -r "s!$H_VERSION_MAJOR_REG!\1$rel_major_version\3!g" $version_header || exit
	[ -z "$H_VERSION_MINOR_REG" ] || sed -i -r "s!$H_VERSION_MINOR_REG!\1$rel_minor_version\3!g" $version_header || exit
	[ -z "$H_VERSION_PATCH_REG" ] || sed -i -r "s!$H_VERSION_PATCH_REG!\1$rel_patch_version\3!g" $version_header || exit 
	[ -z "$H_VERSION_SNAPSHOT_REG" ] || sed -i -r "s!$H_VERSION_SNAPSHOT_REG!\1 0 \3!g"          $version_header || exit 
fi

if [ -f $conanfile_py ]
then
	echo "更新 $conanfile_py"
	sed -i -r "s!(version\s*=\s*\")(.+)(\")!\1$release_version\3!g" $conanfile_py || exit
	git add $conanfile_py || exit
fi 

release_tag=$TAG_PREFIX$release_version
echo "提交对源码的修改 release_version=$release_version"
git add $version_src || exit
[ ! -f $version_header ] || git add $version_header || exit
git commit -m "[verelcm] release $release_tag" || exit

echo "发行版本标签(release_tag=$release_tag)"
git tag $release_tag || exit

# 当前提交id
cur_commit_id=`git rev-parse --short HEAD`
echo "修改源码,改为下一个版本号($next_relver),删除branch,commit_id"
                               sed -i -r "s!$VERSION_REG!\1$next_relver\3!g"              $version_src || exit
[ -z "$VERSION_MAJOR_REG" ] || sed -i -r "s!$VERSION_MAJOR_REG!\1$snap_major_version\3!g" $version_src || exit
[ -z "$VERSION_MINOR_REG" ] || sed -i -r "s!$VERSION_MINOR_REG!\1$snap_minor_version\3!g" $version_src || exit
[ -z "$VERSION_PATCH_REG" ] || sed -i -r "s!$VERSION_PATCH_REG!\1$snap_patch_version\3!g" $version_src || exit 
[ -z "$SNAPSHOT_REG"      ] || sed -i -r "s!$SNAPSHOT_REG!\1.1\3!g"                       $version_src || exit
[ -z "$BEANCH_REG"        ] || sed -i -r "s!$BEANCH_REG!\1$branch\3!g"                    $version_src || exit
[ -z "$COMMIT_REG"        ] || sed -i -r "s!$COMMIT_REG!\1$cur_commit_id\3!g"             $version_src || exit

if [ -f $version_header ] && [ -n "$H_VERSION_MAJOR_REG" ] && [ -n "$H_VERSION_MINOR_REG" ] && [ -n "$H_VERSION_PATCH_REG" ]
then
	echo "更新 $version_header"
	[ -z "$H_VERSION_MAJOR_REG" ] || sed -i -r "s!$H_VERSION_MAJOR_REG!\1$snap_major_version\3!g" $version_header || exit
	[ -z "$H_VERSION_MINOR_REG" ] || sed -i -r "s!$H_VERSION_MINOR_REG!\1$snap_minor_version\3!g" $version_header || exit
	[ -z "$H_VERSION_PATCH_REG" ] || sed -i -r "s!$H_VERSION_PATCH_REG!\1$snap_patch_version\3!g" $version_header || exit 
	[ -z "$H_VERSION_SNAPSHOT_REG" ] || sed -i -r "s!$H_VERSION_SNAPSHOT_REG!\1 1\3!g"            $version_header || exit 
fi

if [ -f $conanfile_py ]
then
	echo "更新 $conanfile_py version=$next_snapshot"
	sed -i -r "s!(version\s*=\s*\")(.+)(\")!\1$next_snapshot\3!g" $conanfile_py || exit
	git add $conanfile_py || exit
fi 

echo "提交对源码的修改"
git add $version_src || exit
[ ! -f $version_header ] || git add $version_header || exit
git commit -m "[verelcm] next development iteration" || exit

#echo "push到远端服务器"
git push || exit
git push origin $release_tag || exit
